package com.github.aloxc.plugin.restplus.common;

import com.github.aloxc.plugin.restplus.entity.*;
import com.github.aloxc.plugin.restplus.utils.JavaScriptUtil;
import com.github.aloxc.plugin.restplus.utils.JsonUtils;
import com.github.aloxc.plugin.restplus.utils.Log;
import com.github.aloxc.plugin.restplus.utils.StringUtils;
import com.google.gson.Gson;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 上传到yapi
 *
 * @author chengsheng@qbb6.com
 * @date 2019/1/31 11:41 AM
 */
public class UploadYapi {

    private Gson gson=new Gson();

    public static String buildApiUrl(String url, String operation){
        url = url.toLowerCase().trim();
        operation = operation.trim();
        if(!url.startsWith("http")){
            url += "http://";
        }
        if(url.endsWith("/")){
            url = url.substring(0,url.length() - 1);
        }
        return url + operation;
    }

    public static String buildViewUrl(String url, String projectId,String id,boolean clazz){
        url = url.toLowerCase().trim();
        if(!url.startsWith("http")){
            url += "http://";
        }
        if(url.endsWith("/")){
            url = url.substring(0,url.length() - 1);
        }
        return String.format(url + (clazz ? Consts.YAPI.CAT_INFO :Consts.YAPI.INFO),projectId,id);
    }

    /**
     * @description: 调用保存接口
     * @param: [yapiSaveParam,  path]
     * @return: com.qbb.dto.YapiResponse
     * @author: chengsheng@qbb6.com
     * @date: 2019/5/15
     */ 
    public YapiResponse uploadSave(YApiSaveParam yapiSaveParam, boolean clazz) throws IOException {
        Log.log(UploadYapi.class.getName(),"aaa1");
        if(StringUtils.isNullOrEmpty(yapiSaveParam.getTitle())){
            yapiSaveParam.setTitle(yapiSaveParam.getPath());
        }
        Log.log(UploadYapi.class.getName(),"aaa2");
        YapiHeaderDTO yapiHeaderDTO=new YapiHeaderDTO();
        if("form".equals(yapiSaveParam.getReq_body_type())){
            yapiHeaderDTO.setName("Content-Type");
            yapiHeaderDTO.setValue("application/x-www-form-urlencoded");
            yapiSaveParam.setReq_body_form(yapiSaveParam.getReq_body_form());
        }else{
            yapiHeaderDTO.setName("Content-Type");
            yapiHeaderDTO.setValue("application/json");
            yapiSaveParam.setReq_body_type("json");
        }
        Log.log(UploadYapi.class.getName(),"aaa3");
        if(Objects.isNull(yapiSaveParam.getReq_headers())){
            List list=new ArrayList();
            list.add(yapiHeaderDTO);
            yapiSaveParam.setReq_headers(list);
        }else{
            yapiSaveParam.getReq_headers().add(yapiHeaderDTO);
        }
        Log.log(UploadYapi.class.getName(),"aaa4");
        YapiResponse yapiResponse= this.getCatIdOrCreate(yapiSaveParam);
        if(yapiResponse.getErrcode() == -1){
            throw new IOException("可能是工程错误、token错误、yapi地址错误，请检查！");
        }
        Log.log(UploadYapi.class.getName(),"aaa5");
        String catId = null;
        if(yapiResponse.getErrcode()==0 && yapiResponse.getData()!=null){
            catId = String.valueOf(yapiResponse.getData());
            yapiSaveParam.setCatid(catId);
            String response=HttpClientUtil.ObjectToString(HttpClientUtil.getHttpclient().execute(this.getHttpPost(buildApiUrl(yapiSaveParam.getYapiUrl(),Consts.YAPI.SAVE),gson.toJson(yapiSaveParam))),"utf-8");
            yapiResponse = gson.fromJson(response, YapiResponse.class);
            if(yapiResponse.getErrcode()!=0){
                return yapiResponse;
            }else{
                List list = (List)yapiResponse.getData();
                String id = null;
                if(list.size() != 0) {
                    // 更新才会返回数据
                    Map map = (Map) list.get(0);
                    id = String.valueOf(map.get("_id")).split("\\.")[0];

                }else{
                    //新增不会返回数据，
                    id = String.valueOf(getApiId(yapiSaveParam).getData()).split("\\.")[0];
                }
                String url = buildViewUrl(yapiSaveParam.getYapiUrl(), String.valueOf(yapiSaveParam.getProjectId()), clazz ? catId:id,clazz);
                yapiResponse.setData(url);
            }
            return yapiResponse;
        }else{
            return yapiResponse;
        }
    }



    /**
     * 获得httpPost
     * @return
     */
    private HttpPost getHttpPost(String url, String body) {
        HttpPost httpPost = null;
        try {
            httpPost = new HttpPost(url);
            httpPost.setHeader("Content-type", "application/json;charset=utf-8");
            HttpEntity reqEntity = new StringEntity(body == null ? "" : body, "UTF-8");
            httpPost.setEntity(reqEntity);
        } catch (Exception e) {
        }
        return httpPost;
    }

    private HttpGet getHttpGet(String url){
        try {
            HttpGet httpGet = HttpClientUtil.getHttpGet(url, "application/json", "application/json; charset=utf-8");
            httpGet.setHeader("User-Agent","Mozilla/5.0(Windows NT 6.1;Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0");
            return httpGet;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }



    /**
     * @description: 获得分类或者创建分类或者
     * @param: [yapiSaveParam]
     * @return: com.qbb.dto.YapiResponse
     * @author: chengsheng@qbb6.com
     * @date: 2019/5/15
     */
    public YapiResponse getCatIdOrCreate(YApiSaveParam yapiSaveParam) {
        String response = null;
        try {
            Log.log(UploadYapi.class.getName(),"param " + JsonUtils.toJson(yapiSaveParam,true));
            String url = buildApiUrl(yapiSaveParam.getYapiUrl() ,Consts.YAPI.CAT_MENU) + "?project_id=" + yapiSaveParam.getProjectId() + "&token=" + yapiSaveParam.getToken();
            Log.log(UploadYapi.class.getName(),"url " + url);
            response = HttpClientUtil.ObjectToString(HttpClientUtil.getHttpclient().execute(this.getHttpGet(url)), "utf-8");
            YapiResponse yapiResponse = gson.fromJson(response, YapiResponse.class);
            Log.log(UploadYapi.class.getName(),"cate.result " + response);
            if (yapiResponse.getErrcode() == 0) {
                List<YapiCatResponse> list = JsonUtils.toBeanList(JsonUtils.toJson(yapiResponse.getData(),false),YapiCatResponse.class);
                for (YapiCatResponse yapiCatResponse : list) {
                    if (yapiCatResponse.getName().equals(yapiSaveParam.getMenu())) {
                        return new YapiResponse(yapiCatResponse.get_id());
                    }
                }
            }
            YapiCatMenuParam yapiCatMenuParam = new YapiCatMenuParam(yapiSaveParam.getMenu(), yapiSaveParam.getProjectId(), yapiSaveParam.getToken());
            String responseCat = HttpClientUtil.ObjectToString(HttpClientUtil.getHttpclient().execute(this.getHttpPost(buildApiUrl(yapiSaveParam.getYapiUrl(),Consts.YAPI.ADD_CAT), gson.toJson(yapiCatMenuParam))), "utf-8");
            YapiCatResponse yapiCatResponse = gson.fromJson(gson.fromJson(responseCat, YapiResponse.class).getData().toString(), YapiCatResponse.class);
            Log.log(UploadYapi.class.getName(),"cate.create.result " + responseCat);
            return new YapiResponse(yapiCatResponse.get_id());
        } catch (IOException e) {
            Writer result = new StringWriter();
            PrintWriter printWriter = new PrintWriter(result);
            e.printStackTrace(printWriter);
            String msg = result.toString();
            msg.replaceAll("\\\\r\\\\n","<br>");
            Log.log1("提交yapi异常" + JavaScriptUtil.class.getName() +"-" ,msg);
            return new YapiResponse(-1, e.toString());
        }
    }

    public YapiResponse getApiId(YApiSaveParam yapiSaveParam) {
        String response = null;
        try {
            String url = buildApiUrl(yapiSaveParam.getYapiUrl() ,Consts.YAPI.API_LIST_IN_CAT) + "?catid=" + yapiSaveParam.getCatid() + "&token=" + yapiSaveParam.getToken() + "&limit=100000";
            response = HttpClientUtil.ObjectToString(HttpClientUtil.getHttpclient().execute(this.getHttpGet(url)), "utf-8");
            YapiResponse yapiResponse = JsonUtils.toBean(response, YapiResponse.class);
            if (yapiResponse.getErrcode() == 0) {
                Map m1 = (Map) yapiResponse.getData();
                List<Map> list = (List<Map>) m1.get("list");
                for (Map map : list) {
                    if (map.get("path").equals(yapiSaveParam.getPath()) && String.valueOf(map.get("project_id")).split("\\.")[0].equals(String.valueOf(yapiSaveParam.getProjectId()))) {
                        return new YapiResponse(map.get("_id"));
                    }
                }
            }
            return yapiResponse;
        } catch (IOException e) {
            return new YapiResponse(-1, e.toString());
        }
    }


}
